from PyQt6.QtWidgets import QWidget
from PyQt6.QtCore import Qt, QPropertyAnimation, QEasingCurve, pyqtProperty
from PyQt6.QtGui import QPainter, QPen, QBrush, QColor, QFont, QLinearGradient
from qfluentwidgets import themeColor, isDarkTheme


class CircularProgress(QWidget):
    def __init__(self, min_val=0, max_val=100, title="", color=None, parent=None):
        super().__init__(parent)
        self.min_val = min_val
        self.max_val = max_val
        self._value = 0  # 实际目标值
        self._animated_value = 0.0  # 用于动画的当前显示值
        self.title = title

        # 使用 Fluent 主题色，如果没有指定颜色的话
        if color:
            self.color = QColor(color)
        else:
            self.color = themeColor()

        self.setFixedSize(180, 180)

        # 创建动画对象
        self.animation = QPropertyAnimation(self, b"animatedValue")
        self.animation.setDuration(600)  # 动画持续时间 600ms
        self.animation.setEasingCurve(QEasingCurve.Type.OutCubic)  # 缓动曲线，让动画更自然

    @pyqtProperty(float)
    def animatedValue(self):
        """动画属性的getter"""
        return self._animated_value

    @animatedValue.setter
    def animatedValue(self, value):
        """动画属性的setter，每次值改变时会触发重绘"""
        self._animated_value = value
        self.update()  # 触发重绘

    @property
    def value(self):
        """获取当前实际值"""
        return self._value

    def setValue(self, value):
        """设置新值并启动动画"""
        # 限制值的范围
        new_value = max(self.min_val, min(value, self.max_val))

        if new_value != self._value:
            old_value = self._animated_value  # 从当前显示值开始动画
            self._value = new_value

            # 配置并启动动画
            self.animation.setStartValue(old_value)
            self.animation.setEndValue(new_value)
            self.animation.start()

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.RenderHint.Antialiasing)

        # 使用动画值计算进度
        progress = (self._animated_value - self.min_val) / (self.max_val - self.min_val)

        # 根据主题选择背景颜色
        if isDarkTheme():
            bg_color = QColor(60, 60, 60)
            text_color = QColor(255, 255, 255)
            title_color = QColor(200, 200, 200)
        else:
            bg_color = QColor(220, 220, 220)
            text_color = QColor(50, 50, 50)
            title_color = QColor(100, 100, 100)

        # 绘制背景环
        pen = QPen(bg_color, 12)
        pen.setCapStyle(Qt.PenCapStyle.RoundCap)
        painter.setPen(pen)
        painter.drawArc(20, 20, 140, 140, 0, 360 * 16)

        # 绘制进度环
        gradient = QLinearGradient(0, 0, 0, 160)
        gradient.setColorAt(0, self.color.lighter(120))
        gradient.setColorAt(1, self.color)
        pen = QPen(QBrush(gradient), 12)
        pen.setCapStyle(Qt.PenCapStyle.RoundCap)
        painter.setPen(pen)
        painter.drawArc(20, 20, 140, 140, 90 * 16, -int(progress * 360 * 16))

        # 绘制中心文字（使用动画值）
        painter.setPen(text_color)
        font = QFont("Microsoft YaHei", 20, QFont.Weight.Bold)
        painter.setFont(font)
        painter.drawText(self.rect(), Qt.AlignmentFlag.AlignCenter, f"{self._animated_value:.1f}%")

        # 绘制标题
        font = QFont("Microsoft YaHei", 10)
        painter.setFont(font)
        painter.setPen(title_color)
        title_rect = self.rect().adjusted(0, 40, 0, 0)
        painter.drawText(title_rect, Qt.AlignmentFlag.AlignCenter, self.title)


# 使用示例
if __name__ == "__main__":
    from PyQt6.QtWidgets import QApplication, QVBoxLayout, QPushButton, QHBoxLayout
    from qfluentwidgets import FluentWindow, setTheme, Theme, PushButton
    import sys

    app = QApplication(sys.argv)
    setTheme(Theme.AUTO)

    window = FluentWindow()
    window.setWindowTitle("平滑动画圆形进度条示例")
    window.resize(800, 600)

    # 创建中心部件
    central_widget = QWidget()
    layout = QVBoxLayout(central_widget)

    # 创建进度条容器
    progress_layout = QHBoxLayout()

    # 创建进度条
    progress1 = CircularProgress(0, 100, "CPU 使用率")
    progress2 = CircularProgress(0, 100, "内存使用率", "#FF6B6B")
    progress3 = CircularProgress(0, 100, "磁盘使用率", "#4ECDC4")

    progress_layout.addWidget(progress1)
    progress_layout.addWidget(progress2)
    progress_layout.addWidget(progress3)

    layout.addLayout(progress_layout)

    # 按钮容器
    button_layout = QHBoxLayout()


    # 测试按钮
    def update_progress():
        import random
        progress1.setValue(random.randint(0, 100))
        progress2.setValue(random.randint(0, 100))
        progress3.setValue(random.randint(0, 100))


    def reset_progress():
        progress1.setValue(0)
        progress2.setValue(0)
        progress3.setValue(0)


    def max_progress():
        progress1.setValue(100)
        progress2.setValue(100)
        progress3.setValue(100)


    btn_random = PushButton("随机更新")
    btn_random.clicked.connect(update_progress)

    btn_reset = PushButton("重置为0")
    btn_reset.clicked.connect(reset_progress)

    btn_max = PushButton("设为100")
    btn_max.clicked.connect(max_progress)

    button_layout.addWidget(btn_random)
    button_layout.addWidget(btn_reset)
    button_layout.addWidget(btn_max)

    layout.addLayout(button_layout)

    # 设置初始值
    progress1.setValue(75)
    progress2.setValue(45)
    progress3.setValue(85)

    window.setCentralWidget(central_widget)
    window.show()
    sys.exit(app.exec())